home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / sep91.zip / 9N09053A < prev    next >
Text File  |  1990-01-16  |  5KB  |  131 lines

  1. Listing 4. Datagram sockets example. Client Program.
  2.  
  3.  
  4. /* getservice -- a datagram transmission example. client program. Works with 
  5.  * the server program 'services'. The program asks the server 'services', which
  6.  * is running on the same machine or in a remote host, for the presence of a 
  7.  * specified service on the server machine. The server looks up the "/etc/services"
  8.  * file and sends an answer to the client. If the service exists, the answer gives
  9.  * its name, the port number and the protocol used.
  10.  *
  11.  *    Usage:   getservice  <server host name>
  12.  */
  13.  
  14. #include   <sys/types.h>
  15. #include   <sys/socket.h>
  16. #include   <netinet/in.h>
  17. #include   <netdb.h>
  18. #include   <signal.h>
  19. #include   <sys/errno.h>
  20.  
  21. #define    FAIL   1             
  22. #define    SUCC   0             
  23.  
  24. #define    PORT_NUMBER   2228   /* arbitrarily chosen free port number
  25.                                  * for client-server communication. Must
  26.                                  * be the same in both client and server
  27.                                  */
  28.  
  29. #define    MAXTRIES   3         /* maximum number of retransmissions before giving up */
  30. #define    PROMPT     printf("Service Sought (ctrl-d to exit) : ")
  31.  
  32. /* ------------------------------------------------------------------- */
  33.  
  34. main(ac, av)
  35.     int ac;   char **av ;
  36. {
  37.     int sock ;                       /* socket descriptor */
  38.     struct sockaddr_in sock_addr ;   /* local socket address structure */
  39.     char *progr_name = av[0] ;       /* the present program name */
  40.     char *server_name = av[1] ;      /* server name given on command line */ 
  41.     char service_name[30] ;          /* service name to be asked for */
  42.     char return_message[256] ;       /* buffer for response from the server */
  43.     struct hostent *host_struct, *gethostbyname() ;
  44.     void error() ;                   /* the same as in listing 1 */
  45.     int num_tries ;                  /* the current number of transmission retries */
  46.     int alarm_handler() ;            /* the new alarm signal handler routine */
  47.     extern int errno ;               /* system call error number */
  48.     
  49.  
  50.     if (ac != 2)  {
  51.         fprintf(stderr, "error -- usage: %s <server name>\n", progr_name) ;
  52.         exit(FAIL) ;
  53.     }
  54.  
  55.     /* get server address */
  56.     if ((host_struct = gethostbyname(server_name)) == NULL)  {
  57.         fprintf(stderr, "%s: unknown server %s\n", progr_name, server_name) ;
  58.         exit(FAIL) ;
  59.     }
  60.     
  61.     /* allocate a datagram socket descriptor */
  62.     if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  63.     error(progr_name, ": error opening socket") ;
  64.  
  65.     /* copy server address and type to socket structure */
  66.     bcopy(host_struct->h_addr, (char *)&sock_addr.sin_addr.s_addr,
  67.           host_struct->h_length) ; 
  68.     sock_addr.sin_port = PORT_NUMBER ;
  69.     sock_addr.sin_family = AF_INET ;
  70.  
  71.     /* redirect alarm signal to new signal handler */
  72.     (void)signal(SIGALRM, alarm_handler) ;
  73.  
  74.     /* send messages to remote host */
  75.  
  76.     while (PROMPT, gets(service_name) != NULL)  {
  77.         num_tries = 0 ;
  78.         for ( ; ; )  {
  79.             int nread ;
  80.             if (sendto(sock, service_name, sizeof service_name, 0, 
  81.                    (struct sockaddr *)&sock_addr, sizeof sock_addr ) == -1)
  82.                 error(progr_name, ": error sending datagram to remote host") ;
  83.  
  84.             /* the "recv" blocks until an answer from the server arrives. Since we
  85.              * are in a connectionless environment, reliable transmission isn't
  86.              * guaranteed. For this reason, and although lost packets are very
  87.              * unlikely, we set up a timeout with the call to alarm. If the timeout
  88.              * expires, we retransmit the nessage a maximum of MAX_TRIES times.
  89.              * We also assume that messages can come only from the 'service' server,
  90.              * otherwise "recvfrom should be used.
  91.              */ 
  92.  
  93.             (void)alarm(5) ;
  94.             if ((nread = recv(sock, return_message, sizeof return_message, 0)) <= 0)  {
  95.                 if (nread < 0 && errno != EINTR)  
  96.                     error(progr_name, ": receive failed") ;
  97.                 if (num_tries++ < MAXTRIES)  
  98.                     continue ;
  99.                 else  {
  100.                     fprintf(stderr, "timeout: no response from %s\n", 
  101.                             server_name) ;
  102.                     exit(FAIL) ;
  103.                 }
  104.             }
  105.             else          /* got an answer from the server */
  106.                 break ;
  107.         }
  108.         (void)alarm(0) ;   /* turn off alarm clock */
  109.         /* print out the server response */
  110.         printf("%s\n", return_message) ;
  111.     }
  112.     putchar('\n') ;
  113.     if (close(sock) == -1)
  114.     error(progr_name, ": error closing socket") ;
  115.     exit(SUCC) ;
  116. }
  117.  
  118. /* --------------------------------------------------------------------- */
  119.  
  120. /* alarm_handler -- new handler for the alarm signal. The default action
  121.  * associated with a signal is reset once caugth, so it must be reset
  122.  * to the intended action each time.
  123.  */
  124.  
  125. int alarm_handler()     
  126. {
  127.     (void)signal(SIGALRM, alarm_handler) ;
  128. }
  129.  
  130. /* --------------------------------------------------------------------- */
  131.